home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Development / Source / MSG Demo 1.4.source Folder / Demo ƒ / Shell ƒ / integrity.c < prev    next >
Text File  |  1994-04-15  |  5KB  |  150 lines

  1. /**********************************************************************\
  2.  
  3. File:        integrity.c
  4.  
  5. Purpose:    This module implements a quick-and-dirty integrity check:
  6.             compare the resource fork and map length to stored values.
  7.  
  8. This program is free software; you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation; either version 2 of the License, or
  11. (at your option) any later version.
  12.  
  13. This program is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. GNU General Public License for more details.
  17.  
  18. You should have received a copy of the GNU General Public License
  19. along with this program in a file named "GNU General Public License".
  20. If not, write to the Free Software Foundation, 675 Mass Ave,
  21. Cambridge, MA 02139, USA.
  22.  
  23. \**********************************************************************/
  24.  
  25. #include "integrity.h"
  26.  
  27. #define RESOURCE_FORK_DATA_LENGTH_OFFSET        8L
  28. #define RESOURCE_FORK_MAP_LENGTH_OFFSET            12L
  29. #define STORED_DATA_LENGTH_OFFSET                128L
  30. #define STORED_MAP_LENGTH_OFFSET                132L
  31. #define TAG_OFFSET                                136L
  32. #define THE_TAG                                    0x16435934
  33.  
  34. Boolean DoIntegrityCheck(Boolean *programIntegritySet)
  35. /* called first thing; can be used either to check program integrity (if it has
  36.    been installed) or to install the integrity checker (if the SHIFT key is
  37.    help down during program launch).  Returns FALSE if program integrity is
  38.    not verified; programIntegritySet is TRUE if this procedure installs the
  39.    integrity checker. */
  40. {
  41.     int                thisFile;
  42.     long            count;
  43.     long            resDataLength, checkData;
  44.     long            resMapLength, checkMap;
  45.     long            resMapOffset;
  46.     int                resAttributes;
  47.     long            tag;
  48.     unsigned int    theKeys[8];
  49.     
  50.     *programIntegritySet=FALSE;
  51.     GetKeys(&theKeys);        /* get raw key map */
  52.     FlushVol(0L, 0);        /* just to be on the safe side */
  53.     
  54.     /* interestingly enough, the new-and-improved functions to open a resource fork
  55.        (HOpenRF & FSpOpenRF) won't work here.  They check permissions and won't
  56.        allow write permission to an already-open resource fork -- so we won't be
  57.        able to install the integrity checker on the fly if we Do The Right Thing™.
  58.        Luckily, the old-and-inferior function (OpenRF) doesn't ask permission... */
  59.     OpenRF(CurApName, 0, &thisFile);
  60.     
  61.     SetFPos(thisFile, 1, RESOURCE_FORK_DATA_LENGTH_OFFSET);
  62.     count=4L;
  63.     /* get length of resource data */
  64.     if (FSRead(thisFile, &count, (Ptr)(&resDataLength))!=noErr)
  65.         return FALSE;
  66.     
  67.     SetFPos(thisFile, 1, RESOURCE_FORK_MAP_LENGTH_OFFSET);
  68.     count=4L;
  69.     /* get length of resource map */
  70.     if (FSRead(thisFile, &count, (Ptr)(&resMapLength))!=noErr)
  71.         return FALSE;
  72.     
  73.     SetFPos(thisFile, 1, TAG_OFFSET);
  74.     count=4L;
  75.     FSRead(thisFile, &count, (Ptr)(&tag));    /* read long-word tag */
  76.     if (tag!=THE_TAG)    /* if not equal to our tag, integrity checker not installed */
  77.     {
  78.         if (theKeys[3]&1)    /* if SHIFT key down, install integrity checker */
  79.         {
  80.             count=4L;
  81.             SetFPos(thisFile, 1, 4L);
  82.             /* get the offset of the start of the resource map in the resource fork */
  83.             if (FSRead(thisFile, &count, (Ptr)(&resMapOffset))!=noErr)
  84.                 return FALSE;
  85.             
  86.             resMapOffset+=22L;    /* resource fork attributes at map+22 */
  87.             count=2L;
  88.             SetFPos(thisFile, 1, resMapOffset);
  89.             /* get old resource fork attributes */
  90.             if (FSRead(thisFile, &count, (Ptr)(&resAttributes))!=noErr)
  91.                 return FALSE;
  92.             
  93.             resAttributes|=0x8000;    /* lock resource fork */
  94.             count=2L;
  95.             SetFPos(thisFile, 1, resMapOffset);
  96.             /* rewrite new resource fork attributes */
  97.             /* It is a little-known fact that this trick makes the application
  98.                immune to all known viruses -- no known virus bothers to unlock the
  99.                resource fork before attempting to infect, and ABSOLUTELY NO changes
  100.                can be made to the resource fork when it's locked like this.  On the
  101.                other hand, you better be damn sure that the application has no
  102.                viruses in it when you install the integrity checker -- if it's
  103.                infected when this code is run, you won't be able to disinfect it
  104.                until you unlock the resource fork. */
  105.             if (FSWrite(thisFile, &count, (Ptr)(&resAttributes))!=noErr)
  106.                 return FALSE;
  107.             
  108.             SetFPos(thisFile, 1, STORED_DATA_LENGTH_OFFSET);
  109.             count=4L;
  110.             /* store length of resource data */
  111.             if (FSWrite(thisFile, &count, (Ptr)(&resDataLength))!=noErr)
  112.                 return FALSE;
  113.             
  114.             SetFPos(thisFile, 1, STORED_MAP_LENGTH_OFFSET);
  115.             count=4L;
  116.             /* store length of resource map */
  117.             if (FSWrite(thisFile, &count, (Ptr)(&resMapLength))!=noErr)
  118.                 return FALSE;
  119.             
  120.             SetFPos(thisFile, 1, TAG_OFFSET);
  121.             count=4L;
  122.             tag=THE_TAG;
  123.             /* store tag so we know integrity checker is installed */
  124.             if (FSWrite(thisFile, &count, (Ptr)(&tag))!=noErr)
  125.                 return FALSE;
  126.             
  127.             *programIntegritySet=TRUE;        /* so we know we've installed it */
  128.         }
  129.         
  130.         return TRUE;
  131.     }
  132.     else
  133.     {
  134.         SetFPos(thisFile, 1, STORED_DATA_LENGTH_OFFSET);
  135.         count=4L;
  136.         /* get stored resource data length */
  137.         if (FSRead(thisFile, &count, (Ptr)(&checkData))!=noErr)
  138.             return FALSE;
  139.         
  140.         SetFPos(thisFile, 1, STORED_MAP_LENGTH_OFFSET);
  141.         count=4L;
  142.         /* get stored resource map length */
  143.         if (FSRead(thisFile, &count, (Ptr)(&checkMap))!=noErr)
  144.             return FALSE;
  145.         
  146.         /* check real resource data/map lengths to stored values */
  147.         return ((resDataLength==checkData) && (resMapLength==checkMap));
  148.     }
  149. }
  150.